package repository

import (
	v1 "server_go/api/v1"
	"server_go/internal/model"
	"server_go/pkg/md5"
)

type UserRepository interface {
	GetUserById(userId int64) (*model.User, error)
	GetUserByAccount(account string) (*model.User, error)
	AddUser(user *model.User) error
	DeleteUser(userId int64) error
	UpdateUser(userId int64, user *model.User) error
	GetAllUser(page, pageSize int) ([]*model.User, int64, error)
	GetTypeByUserAccount(account string) (int8, error)
}

func NewUserRepository(repository *Repository) UserRepository {
	return &userRepository{
		Repository: repository,
	}
}

type userRepository struct {
	*Repository
}

func (r *userRepository) GetUserById(userId int64) (*model.User, error) {
	var count int64
	if err := r.db.Table("user").
		Where("id = ? AND deleted_at IS NULL", userId).
		Count(&count).Error; err != nil {
		return nil, err
	}
	if count == 0 {
		return nil, v1.ErrUserNotExist
	}
	var user *model.User
	if err := r.db.Table("user").Where("id = ?", userId).First(&user).Error; err != nil {
		return nil, err
	}
	return user, nil
}
func (r *userRepository) GetUserByAccount(account string) (*model.User, error) {
	var count int64
	if err := r.db.Table("user").
		Where("account = ? AND deleted_at IS NULL", account).
		Count(&count).Error; err != nil {
		return nil, err
	}
	if count == 0 {
		return nil, v1.ErrUserNotExist
	}
	var user *model.User
	if err := r.db.Table("user").Where("account = ?", account).First(&user).Error; err != nil {
		return nil, err
	}
	return user, nil
}
func (r *userRepository) AddUser(user *model.User) error {
	if err := r.db.Table("user").Create(&user).Error; err != nil {
		return err
	}
	return nil
}
func (r *userRepository) DeleteUser(userId int64) error {
	if err := r.db.Table("user").Delete(&model.User{}, userId).Error; err != nil {
		return err
	}
	return nil
}
func (r *userRepository) UpdateUser(userId int64, user *model.User) error {
	updates := make(map[string]interface{})
	if user.Username != "" {
		updates["username"] = user.Username
	}
	if user.Password != "" {
		updates["password"] = md5.Md5(user.Password)
	}
	if user.Describe != "" {
		updates["describe"] = user.Describe
	}
	if user.AvatarId != 0 {
		updates["avatar_id"] = user.AvatarId
	}
	if user.Status != 0 {
		updates["status"] = user.Status
	}
	if err := r.db.Table("user").Where("id = ?", userId).Updates(updates).Error; err != nil {
		return err
	}
	return nil
}
func (r *userRepository) GetAllUser(page, pageSize int) ([]*model.User, int64, error) {
	users := make([]*model.User, 0)
	offset := (page - 1) * pageSize
	if err := r.db.Table("user").
		Where("type = 2").
		Limit(pageSize).Offset(offset).Find(&users).Error; err != nil {
		return nil, 0, err
	}
	var total int64
	if err := r.db.Table("user").
		Where("deleted_at IS NULL AND type = 2").
		Count(&total).Error; err != nil {
		return nil, 0, err
	}
	return users, total, nil
}

func (r *userRepository) GetTypeByUserAccount(account string) (int8, error) {
	var user model.User
	if err := r.db.Table("user").
		Where("account = ?", account).
		First(&user).Error; err != nil {
		return 0, err
	}
	return user.Type, nil
}
